package craky.keeper;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import com.sun.awt.AWTUtilities;

import craky.component.JImagePane;
import craky.componentc.CRootPaneUI;
import craky.componentc.JCButton;
import craky.componentc.JCFrame;
import craky.componentc.JCLabel;
import craky.componentc.JCToggleButton;
import craky.keeper.allpay.AllPayPane;
import craky.keeper.electricity.ElePane;
import craky.keeper.extra.ExtraPane;
import craky.keeper.gas.GasPane;
import craky.keeper.house.HousePane;
import craky.keeper.skin.SkinMenu;
import craky.keeper.user.User;
import craky.keeper.util.KeeperUtil;
import craky.keeper.water.WaterPane;
import craky.layout.LineLayout;
import craky.util.Config;
import craky.util.UIUtil;

public class MainFrame extends JCFrame {
	private static final long serialVersionUID = -1008270690673070592L;
	private KeeperApp keeper;
	private KeeperMgr mgr;
	private Config config;
	private Map<String, KeeperPane> paneMap;
	private JImagePane titleContent;
	private JImagePane mainPane;
	private JCToggleButton btnAll;
	private JCToggleButton btnWater;
	private JCToggleButton btnEle;
	private JCToggleButton btnGas;
	private JCToggleButton btnHouse;
	private JCToggleButton btnExtra;
	private JCButton btnReload;
	private JCButton btnSetting;
	private JImagePane statusBar;
	private JCLabel lbStatusInfo;
	private JCLabel lbTotal;
	private JCLabel lbAmount;
	private SkinMenu skinMenu;
	private CardLayout cardLayout;
	private AbstractButton[] buttons;
	private KeeperPane[] keeperPanes;

	public MainFrame(KeeperApp keeper) {
		this.keeper = keeper;
		this.mgr = new KeeperMgr(keeper, this);
		this.config = keeper.getConfig();
		this.titleContent = getTitleContentPane();
		this.paneMap = new HashMap<String, KeeperPane>();
		initUI();
		setTabForegroundDes(this.config.getProperty("Tabs_Foreground",
				"225,242,250"));
		setStatusForegroundDes(this.config.getProperty("Status_Foreground",
				"225,242,250"));
		AWTUtilities.setWindowOpacity(this,
				Float.valueOf(this.config.getProperty("Win_Alpha", "1.0"))
						.floatValue());
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				MainFrame.this.keeper.exit();
			}
		});
		UIUtil.registerKeyEvent(this, new AbstractAction() {
			private static final long serialVersionUID = 2054393387947500297L;

			public void actionPerformed(ActionEvent e) {
				MainFrame.this.mgr.reload();
			}
		}, "F5", 116, 0);
		UIUtil.registerKeyEvent(this, new AbstractAction() {
			private static final long serialVersionUID = 7021461035699115902L;

			public void actionPerformed(ActionEvent e) {
				MainFrame.this.mgr.submit();
			}
		}, "Ctrl+Enter", 10, 2);
		setVisible(true);
	}

	private void initUI() {
		JPanel content = (JPanel) getContentPane();
		setDefaultCloseOperation(0);
		setTitle("三号管家 - 1.0.3");
		setIconImage(KeeperUtil.getImage("logo_16.png"));
		content.setLayout(new BorderLayout());
		content.setBorder(new EmptyBorder(0, 2, 5, 2));
		setMinimumSize(new Dimension(800, 550));
		setSize(KeeperUtil.stringToSize(this.config.getProperty("Win_Size",
				"900,600")));
		setLocationRelativeTo(null);
		setTitleOpaque(Boolean.valueOf(
				this.config.getProperty("Title_Opaque", "false"))
				.booleanValue());
		setImageDisplayMode(CRootPaneUI.ImageDisplayMode.valueOf(this.config
				.getProperty("Skin_Mode", "FILL")));
		setImageAlpha(Float.valueOf(
				this.config.getProperty("Skin_Alpha", "0.50")).floatValue());
		this.titleContent.setLayout(new LineLayout(0, 0, 0, 2, 0, 11, 10, 0));
		initMenu();
		initButtons();
		initPanes();
		this.btnAll.setSelected(true);

		if (Boolean.parseBoolean(this.config.getProperty("Win_Maximized",
				"false"))) {
			setExtendedState(6);
		}
	}

	private void initMenu() {
		JMenuBar bar = new JMenuBar();
		bar.setOpaque(false);
		bar.setBorder(new EmptyBorder(0, 0, 0, 0));
		bar.setBorderPainted(false);
		bar.setLayout(new GridLayout(1, 2));
		bar.setPreferredSize(new Dimension(40, 20));
		bar.setFocusable(false);
		bar.add(new KeeperMenu(this.keeper, this.mgr));
		bar.add(this.skinMenu = new SkinMenu(this.keeper));
		this.titleContent.add(bar, "End");
		resetSkinPopupLocation();
	}

	private void initButtons() {
		boolean isVisitor = this.keeper.getCurrentUser().getPurview() >= 20;
		Dimension buttonSize = new Dimension(84, 78);
		ButtonGroup group = new ButtonGroup();
		Image normalImage = KeeperUtil.getImage("tab_button_normal.png", true);
		Image selImage = KeeperUtil.getImage("tab_button_chosen.png", true);
		this.btnAll = new JCToggleButton("日常支出");
		this.btnWater = new JCToggleButton("水费");
		this.btnEle = new JCToggleButton("电费");
		this.btnGas = new JCToggleButton("燃气贄");
		this.btnHouse = new JCToggleButton("住房支出");
		this.btnExtra = (isVisitor ? null : new JCToggleButton("额外支出"));
		this.btnReload = new JCButton("刷新");
		this.btnSetting = new JCButton("设置");
		this.buttons = new AbstractButton[] { this.btnAll, this.btnWater,
				this.btnEle, this.btnGas, this.btnHouse, this.btnExtra,
				this.btnReload, this.btnSetting };
		this.keeperPanes = new KeeperPane[] {
				new AllPayPane(this.keeper, this.mgr),
				new WaterPane(this.keeper, this.mgr),
				new ElePane(this.keeper, this.mgr),
				new GasPane(this.keeper, this.mgr),
				new HousePane(this.keeper, this.mgr),
				isVisitor ? null : new ExtraPane(this.keeper, this.mgr) };
		String[] iconNames = { "all_pay.png", "water.png", "eletricity.png",
				"gas.png", "house.png", "extra.png", "reload.png",
				"setting.png" };

		int index = 0;

		//System.out.println("this.keeperPanes=" + this.keeperPanes.length);

		System.out.println("this.buttons=" + this.buttons.length);
		for (AbstractButton button : this.buttons) {
			if (button != null) {
				group.add(button);
				button.setIcon(KeeperUtil.getIcon(iconNames[index]));
				button.setPreferredSize(buttonSize);
				button.setFocusable(false);
				button.setVerticalTextPosition(3);
				button.setHorizontalTextPosition(0);
				button.setIconTextGap(0);
				if (index < (this.keeperPanes.length - 1))
					button.putClientProperty("LinkedComponent",
							this.keeperPanes[index]);

				if ((button instanceof JCToggleButton)) {
					JCToggleButton ctb = (JCToggleButton) button;
					ctb.setPaintPressDown(false);
					ctb.setImage(normalImage);
					ctb.setRolloverImage(selImage);
					ctb.setSelectedImage(selImage);
					ctb.setActionCommand("ShowKeeperPane");
					ctb.addItemListener(this.mgr);
				} else {
					JCButton cb = (JCButton) button;
					cb.setImage(normalImage);
					cb.setRolloverImage(selImage);
					cb.setPressedImage(selImage);
					cb.addActionListener(this.mgr);
				}
			}

			index++;
		}

		this.btnReload.setActionCommand("Reload");
		this.btnSetting.setActionCommand("Setting");
	}

	private void initPanes() {
		this.mainPane = new JImagePane();
		JPanel buttonPane = new JPanel();
		buttonPane.setPreferredSize(new Dimension(-1, 78));
		buttonPane.setBorder(new EmptyBorder(0, 5, 0, 0));
		buttonPane.setOpaque(false);
		buttonPane.setLayout(new LineLayout(0, 0, 0, 0, 0, 10, 10, 0));
		this.mainPane.setImageOnly(false);
		this.mainPane.setBackground(new Color(255, 255, 255, 230));
		this.mainPane.setLayout(this.cardLayout = new CardLayout());

		for (AbstractButton button : this.buttons) {
			if (button == null)
				continue;
			Object linkedObject = button.getClientProperty("LinkedComponent");
			buttonPane.add(button, "Start");

			if ((linkedObject == null)
					|| (!(linkedObject instanceof KeeperPane)))
				continue;
			KeeperPane keeperPane = (KeeperPane) linkedObject;
			this.mainPane.add(keeperPane, keeperPane.getName());
			this.paneMap.put(keeperPane.getType(), keeperPane);
		}

		getContentPane().add(buttonPane, "North");
		getContentPane().add(initStatusBar(), "South");
		getContentPane().add(this.mainPane, "Center");
	}

	private JComponent initStatusBar() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		User user = this.keeper.getCurrentUser();
		this.statusBar = new JImagePane();
		JCLabel lbDate = new JCLabel(format.format(new Date()));
		this.lbStatusInfo = new JCLabel("当前用户" + user.getName() + "("
				+ user.getPurviewName() + ")");
		this.lbTotal = new JCLabel("记录条数");
		this.lbAmount = new JCLabel("总金额");
		JCButton btnCancelSavedPassword = null;
		this.statusBar.setImageOnly(true);
		this.statusBar.setPreferredSize(new Dimension(-1, 21));
		this.statusBar.setBorder(new EmptyBorder(4, 5, 3, 5));
		this.statusBar.setLayout(new LineLayout(8, 0, 0, 0, 0, 10, 10, 0));
		this.lbAmount.setBorder(new EmptyBorder(0, 5, 0, 5));
		this.statusBar.add(this.lbTotal, "EedFill");
		this.statusBar.add(this.lbAmount, "EedFill");

		if (user.isSavePassword()) {
			btnCancelSavedPassword = new JCButton("取消记住密码");
			btnCancelSavedPassword.setFocusable(false);
			btnCancelSavedPassword.setImage(null);
			btnCancelSavedPassword.setActionCommand("CancelSavedPassword");
			btnCancelSavedPassword.addActionListener(this.mgr);
			this.statusBar.add(btnCancelSavedPassword, "EedFill");
		}

		if (user.isAutoLogin()) {
			JCButton btnCancelAutoLogin = new JCButton("取消自动登陆");
			btnCancelAutoLogin.setFocusable(false);
			btnCancelAutoLogin.setImage(null);
			btnCancelAutoLogin.setActionCommand("CancelAutoLogin");
			btnCancelAutoLogin.addActionListener(this.mgr);
			btnCancelSavedPassword.putClientProperty("LinkedComponent",
					btnCancelAutoLogin);
			this.statusBar.add(btnCancelAutoLogin, "EedFill");
		}

		this.statusBar.add(lbDate, "EedFill");
		this.statusBar.add(this.lbStatusInfo, "MiddleFill");
		return this.statusBar;
	}

	public void resetSkinPopupLocation() {
		this.skinMenu.setMenuLocation(Integer.parseInt(this.config.getProperty(
				"Skin_Popup_X", "-216")),
				this.skinMenu.getPreferredSize().height);
	}

	public void setTabForegroundDes(String colorDes) {
		Color color = KeeperUtil.stringToColor(colorDes);

		if (color != null) {
			setTabForeground(color);
		}
	}

	public String getTabForegroundDes() {
		return KeeperUtil.colorToString(getTabForeground());
	}

	public void setTabForeground(Color fg) {
		for (AbstractButton button : this.buttons) {
			if (button == null)
				continue;
			button.setForeground(fg);
		}
	}

	public Color getTabForeground() {
		return this.btnAll.getForeground();
	}

	public void setStatusForegroundDes(String colorDes) {
		Color color = KeeperUtil.stringToColor(colorDes);

		if (color != null) {
			setStatusForeground(color);
		}
	}

	public String getStatusForegroundDes() {
		return KeeperUtil.colorToString(getStatusForeground());
	}

	public void setStatusForeground(Color fg) {
		this.statusBar.setForeground(fg);

		for (Component c : this.statusBar.getComponents()) {
			c.setForeground(fg);
		}
	}

	public Color getStatusForeground() {
		return this.statusBar.getForeground();
	}

	public void setStatus(String status) {
		this.lbStatusInfo.setText(status);
	}

	public void resetTotal(int total, float amount) {
		this.lbTotal.setText("记录条数" + total);
		this.lbAmount.setText("总金额" + KeeperConst.AMOUNT_FORMAT.format(amount));
		this.statusBar.doLayout();
	}

	public void showPane(String name) {
		this.cardLayout.show(this.mainPane, name);
	}

	public void updateCategory() {
		for (KeeperPane pane : this.keeperPanes) {
			if (pane == null)
				continue;
			pane.updateCategory();
		}
	}

	public KeeperPane getPaneByType(String type) {
		return this.paneMap.get(type);
	}
}